/******************************************************************************/
/*! 
    NScope
    [2012]

    \NScope.h
    \Core
    \brief      
*/
/******************************************************************************/
/*** Include guard ************************************************************/
#ifndef SCOPE_H
#define SCOPE_H
/*** Includes *****************************************************************/
//Engine
#include "NDatum.h"
#include "NSerializable.h"
//Stl
#include <vector>
#include <hash_map>

/*** Forward Declarations *****************************************************/

/*** Namespace ****************************************************************/
namespace Core
{
/*** Macros *******************************************************************/

/*** Constants ****************************************************************/
const int SIZE_MULTIPLIER = 2;

/*** Interface ****************************************************************/
class NScope : public Core::NSerializable
{
	typedef std::pair<std::string, NDatum>			Dictionary_Pair;
	typedef std::hash_map<std::string, NDatum>		Dictionary;

	typedef std::pair<std::string, NDatum*>			List_Pair;
	typedef	std::vector<List_Pair>					List;

	RTTI_DECLARATIONS(NScope, NSerializable)

public:
	NScope(void);
	
	NScope(unsigned int initCapacity);
	
	NScope(const NScope& rhs);
	
	virtual ~NScope(void);
	
	NScope& operator=(const NScope& rhs);
	
	NDatum& operator[](std::string name);
	
	NDatum& operator[](unsigned int index);
	
	bool operator==(const NScope& rhs) const;
	
	bool operator!=(const NScope& rhs) const;
	
	void CopyValues(const NScope& aScope, bool overWrite = false);
	
	NDatum* Find(std::string name) const;
	
	int Index_Find(std::string name) const;
	
	bool Search(std::string name, NDatum** aDatum = 0, NScope** foundScope = 0) const;

	NDatum& Append(std::string datumName);
	
	NScope& AppendScope(std::string name, unsigned int index = 0);
	
	void Adopt(NScope* aScope, std::string name, unsigned int index = 0);
	
	NScope* GetParent() const { return mParent; }
	
	bool ReverseFind(NScope * findScope, char ** nameFound);
	
	std::string GetMemberName(unsigned int index) const;

	void Clear();
	
	void Orphan();
	
	unsigned int NScope::Size() const { return mSize; }
	
	void ReserveSpace(unsigned int size);
	
private:
	void CheckVectorSize();
	
	void RemoveScope(NScope & aScope);

	bool SearchForParent(NScope & rhs) const;

	void BoundsCheck(unsigned int index) const;

	void CapcityCheck();

	unsigned int mSize;				 //!<	number of elements in the table
	List mOrderedList;				 //!<	ordered collection of pointers to pairs 
	Dictionary mEntryDictionary;	 //!<	map of owned pairs
	NScope* mParent;				 //!<	pointer to owner/parent of this scope
};
}
#endif